package freedom.platform.action;

import java.util.ArrayList;
import java.util.List;

import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;

import freedom.platform.dao.RoleDao;
import freedom.platform.model.Role;
import freedom.utils.ExampleMatcherUtils;

@Controller
@Scope("prototype")
@Results({@Result(name = "success", type = "redirectAction", params = {"actionName", "roles"})})
public class RolesController extends ActionSupport implements ModelDriven<Role>  {

    private static final long serialVersionUID = 1L;

    @Autowired
    private RoleDao roleDao;

    private Role model;
    private List<Role> list;

    // GET /roles
    public HttpHeaders index() {
        ExampleMatcher em = ExampleMatcher.matching();
        em = ExampleMatcherUtils.withIgnoreBlankValues(em, model);
        em = em.withMatcher(Role.PROP_NAME, GenericPropertyMatchers.contains());
        Example<Role> e = Example.of(model, em);

        List<Order> orders = new ArrayList<Order>(1);
        orders.add(new Order(Direction.DESC, Role.PROP_UPDATE_TIME));
        Sort sort = new Sort(orders);
        list = roleDao.findAll(e, sort);
        return new DefaultHttpHeaders("index").disableCaching();
    }

    // GET /roles/1
    public HttpHeaders show() {
        model = roleDao.getOne(model.getId());
        return new DefaultHttpHeaders("show").withETag(Role.PROP_UPDATE_TIME).lastModified(model.getUpdateTime());
    }

    // GET /roles/1/edit
    public String edit() {
        model = roleDao.getOne(model.getId());
        return "edit";
    }

    // GET /roles/new
    public String editNew() {
        model = new Role();
        return "editNew";
    }

    // GET /roles/1/deleteConfirm
    public String deleteConfirm() {
        return "deleteConfirm";
    }

    // DELETE /roles/1
    public String destroy() {
        roleDao.delete(model.getId());
        addActionMessage("Role removed successfully");
        return "success";
    }

    // POST /roles
    @Validations(
        requiredStrings = {@RequiredStringValidator(fieldName = Role.PROP_NAME,
            message = "%{getText('pleaseInput','',getText('" + Role.PROP_NAME + "'))}")},
        stringLengthFields = {@StringLengthFieldValidator(fieldName = Role.PROP_DESCRIPTION, maxLength = "255")})
    public HttpHeaders create() {
        if (null != roleDao.findByName(model.getName())) {
            this.addFieldError(Role.PROP_NAME, getText("role_existed"));
            return new DefaultHttpHeaders("input");
        }
        model.mark(true);
        roleDao.save(model);
        addActionMessage("New role created successfully");
        return new DefaultHttpHeaders("success").setLocationId(model.getId());
    }

    // PUT /roles/1
    public String update() {
        model.mark(false);
        roleDao.save(model);
        addActionMessage("Role updated successfully");
        return "success";
    }

    public Role getModel() {
        if (this.model == null)
            this.model = new Role();
        return this.model;
    }

    public List<Role> getList() {
        return list;
    }

    public void setList(List<Role> list) {
        this.list = list;
    }
    
}
